/* ConfReader.cpp
 * Author: mtreece
 * Date Started: 01/22/2010
 * Purpose:
 *  Reads a configuration file and parses
 *  it for information of the form:
 *      VALUE=value
 *         or
 *      VALUE = value (tokenized via whitespace)
 */

#include <iostream>
#include <fstream>

#include <ctype.h>
#include <string.h>

#include "ConfReader.h"

using namespace std;

ConfReader::ConfReader(const char * filename){
	file.open(filename, ifstream::in);
	strcpy(FileName, filename); // for easy access later
}

ConfReader::~ConfReader(){
	file.close();
}

int ConfReader::isReady(){
	return file.good() == true ? 1 : 0;
}

/* After setting this object a file
 * to work with, this method returns
 * the value associated with
 * valueName.
 * 
 * If not found, returns null pointer.
 */
char * ConfReader::getValue(const char * valueName){
	char * startLoc = buffer;
 	file.seekg(0); // reset file location

	while(! file.getline(buffer, MAXBUFFER).eof() && !file.fail()){
		// if in here, we've not hit EOF
		// and we have the next line in 
		// the char buffer[]
		
		// Check to see if this line is the 
		// one we want...

		// Jump ahead of whitespace...
		// while(isspace(*startLoc)) startLoc++;
		jumpChars(&startLoc);

		// Test if comment..., if so, next line...
		if(*startLoc == '#'){
			continue;
		}

		// Test if this is the matching line...
		if(startMatch(valueName, startLoc)){
			// jump past [value]
			startLoc += strlen(valueName);

			// jump over the '=' and whitespace
			jumpChars(&startLoc);

			strcpy(buffer2, startLoc);
			return buffer2;
		}
	}
	file.close();
	file.open(FileName, ifstream::in);
	return (char *) 0;
}

/* Determine if dest is src
 */
int ConfReader::startMatch(const char * src, const char * dest){
	unsigned int len = strlen(src);
	if(len > strlen(dest)){
		return 0;
	}
	const char * tester = dest + strlen(src);
	int good = 0;
	for(unsigned int i=0; i<strlen(dest); i++){
		/* Idea:
		 *   If we encounter a '=', set
		 *   a flag that we've satisfied
		 *   the condition, and break for
		 *   further processing.
		 *   If not a '=', but not a space,
		 *   then we have a problem, thus
		 *   not what we're looking for,
		 *   thus, break.
		 *
		 * FIXME: Implement only one '=' ?
 		 */
		if(tester[i] == '='){
			good = 1;
			break;
		}
		if(!isspace(tester[i])) return 0;
	}
	if(!good) return 0;
	for(unsigned int i=0; i<len; i++){
		if(*src != *dest){
			return 0;
		}
		src++, dest++;
	}
	return 1;
}

void ConfReader::jumpChars(char ** src){
	while(isspace(**src) || **src == '='){
		(*src)++;
	}
}

/*
int main(int argc, char *argv[]){
	if(argc > 1 && strcmp(argv[1],"--test") == 0){
		const char CONF_FILE[] = "test.conf";
		char inputBuffer[500];
		printf("Testing conf-file: '%s'\n", CONF_FILE);
		ConfReader x(CONF_FILE);
		while(1){
			printf("Read what value? ");
			scanf("%s", inputBuffer);
			printf("Value '%s' has: '%s'\n", 
				inputBuffer, x.getValue(inputBuffer));
		}
	}
		return 0;
}*/
